home *** CD-ROM | disk | FTP | other *** search
/ PCMania 64 / PCMania CD64_1.iso / phy / phy005 / files / articulo.t12 < prev    next >
Encoding:
Text File  |  1997-02-20  |  11.0 KB  |  1 lines

  1. ε                        Optimización en ensamblador                                 ε                        ---------------------------                                                                                                                              Continuamos con este cursillo de optimización. El número pasado vimos        un poco de optimización en comparaciones, y hoy vamos a empezar con optimiza-        ción de código.                                                                                                                                                                   Para empezar, podemos ver el siguiente ejemplo: una rutina completamen-      te sin optimizar que de ser así sería bastante más lenta de lo que podría ser        optimizada. Vamos a verla:                                                                                                                                                Γ                        MOV     CX, 0100h                                           Γ                        PUSH    CS                                                  Γ                        POP     DS                                                  Γ                        PUSH    CS                                                  Γ                        POP     ES                                                  Γ                        MOV     DI, Offset Origen                                   Γ                        MOV     BX, Offset Destino                                  Γ             @@Loop:    MOV     DL, [DI]                                            Γ                        CMP     DL, 20h                                             Γ                        JZ    @@FinLoop                                             Γ                        MOV     [BX], DL                                            Γ                        INC     DI                                                  Γ                        INC     BX                                                  Γ                        LOOP  @@Loop                                                Γ          @@FinLoop:    CMP     CX, 0000                                            Γ                        JZ    @@NoSeHaEncontradoUnEspacio                           Γ                        ...                                                                                                                                                      Esta porción de código, desde el punto de vista de optimización, es          horrible. Esto haría que copiemos una cadena en la dirección [Origen] a una          dirección de memoria [Destino] hasta que encontremos un espacio. Optimicemos         paso a paso:                                                                                                                                                                      Existen las instrucciones δLODSBπ y δSTOSBπ. δLODSBπ coge el byte que apun-  ta ΩDS:SIπ y lo carga en ΩALπ, y ΩSTOSBπ almacena el byte ΩALπ en la zona en memoria apuntada por δES:DIπ. Además, el puntero en DS:SI y ES:DI se incrementa o decre-     menta según la bandera δDπ (Direction Flag) esté a 1 o a 0 (si está a 0 se incre-    menta, y a 1 se decrementa). Por tanto, usemos esto en el código. En vez de          usar DL como variable para almacenar lo que cogemos de [Origen], usemos AL, y        en vez de usar DI para el origen y BX para el destino, usemos SI para el origen      y DI para el destino:                                                                                                                                                     Γ                        MOV     CX, 0100h                                           Γ                        PUSH    CS                                                  Γ                        POP     DS                                                  Γ                        PUSH    CS                                                  Γ                        POP     ES                                                  Γ                        MOV     SI, Offset Origen                                   Γ                        MOV     DI, Offset Destino                                  Γ                        CLD                     ; Pone la Direction Flag a 0        Γ            @@Loop:     LODSB                                                       Γ                        CMP     AL, 20h                                             Γ                        JZ    @@FinLoop                                             Γ                        STOSB                                                       Γ                        LOOP  @@Loop                                                Γ         @@FinLoop:     CMP     CX, 0000                                            Γ                        JZ    @@NoSeHaEncontradoUnEspacio                           Γ                        ...                                                                                                                                                      Bien, no sólo hemos aumentado la velocidad de este algoritmo, si no que      además hemos reducido su tamaño. Pero vemos más animaladas, entre ellas la com-      probación δCMP CX,0000π. Podríamos reducirlo a  δOR CX,CX/JNZ ...π , pero aún así    no está completamente optimizado. Usamos, entonces, la instrucción δJCXZπ. Esta      instrucción es una instrucción de salto que se efectuará si CX es igual a 0.         Lo malo de ésta es que no permite saltos de más de 128 bytes de longitud, pero       si sabemos que éste no va a ser nuestro caso, la usamos:                                                                                                                  Γ                        ...                                                         Γ                        STOSB                                                       Γ                        LOOP  @@Loop                                                Γ         @@FinLoop:     JCXZ  @@NoSeHaEncontradoUnEspacio                           Γ                        ...                                                                                                                                                      Y encima de más velocidad conseguimos reducción de código. Si seguimos       repasando el código, nos encontramos con la última falta: LOOP. No es que LOOP       sea una instrucción de poca optimización, pero resulta que el par δDEC CX/JNZ...     es más rápido, al menos hasta el Pentium. Pero como no programamos para Pentium      (de momento), habrá que desistir de usar LOOP. Así que, tocando esto último,         miramos cómo nos ha quedado el código resultante:                                                                                                                         Γ                        MOV     CX, 0100h                                           Γ                        PUSH    CS                                                  Γ                        POP     DS                                                  Γ                        PUSH    CS                                                  Γ                        POP     ES                                                  Γ                        MOV     SI, Offset Origen                                   Γ                        MOV     DI, Offset Destino                                  Γ             @@Loop:    LODSB                                                       Γ                        CMP     AL, 20h                                             Γ                        JZ    @@FinLoop                                             Γ                        STOSB                                                       Γ                        DEC     CX                                                  Γ                        JNZ   @@Loop                                                Γ          @@FinLoop:    JCXZ  @@NoSeHaEncontradoUnEspacio                           Γ                        ...                                                                                                                                                      No sólo es más corto, sino más rápido (de buen trozo). Y, mirando mi-        rando, nos damos cuenta de que aún podemos optimizarlo más aún. Si lo miramos        bien, podemos ver que no hay ninguna necesidad de saltar a @@FinLoop después         de comprobar que AL es 20h, sino que podemos saltar directamente al sitio que        toca, y no utilizar @@FinLoop como lugar de paso tanto si se ha encontrado un        espacio como si no, y tener que utilizar JCXZ para determinar si se encontró un      espacio o no. Vamos a implementarlo:                                                                                                                                      Γ                        MOV     CX, 0100h                                           Γ                        PUSH    CS                                                  Γ                        POP     DS                                                  Γ                        PUSH    CS                                                  Γ                        POP     ES                                                  Γ                        MOV     SI, Offset Origen                                   Γ                        MOV     DI, Offset Destino                                  Γ           @@Loop:      LODSB                                                       Γ                        CMP     AL, 20h                                             Γ                        JZ    @@SeEncontróUnEspacio                                 Γ                        STOSB                                                       Γ                        DEC     CX                                                  Γ                        JNZ   @@Loop                                                Γ                        JMP   @@NoSeHaEncontradoUnEspacio                           Γ@@SeEncontroUnEspacio:  ...                                                                                                                                                                                                                                           Ante todos estos cambios, pensamos: pero, ¿de verdad hace falta redu-        cir tanto un código si hace lo mismo? Tenemos que tener en cuenta que es mejor       cuanto más veloz. Imaginaos que tenéis que hacer el algoritmo 20000 veces. Con       el primer ejemplo, seguro que tardaba el doble que el primero en hacerse, y así      se notaría bastante la velocidad.                                                                                                                                                 Bueno, ya está bien por ahora. En el próximo número veremos instruccio-      nes que pueden ser sustituidas por grupos de instrucciones que en conjunto se-       rán más rápidas que la original. Hasta la próxima!                                                                                                                        ∞                                                Líyak el Oscuro